#include "QcPickResultListItemDelegate.h"
#include "QcGroupedListView.h" // 用来获取branch尺寸
#include "QcPickResultView.h" // 用来获取expaned状态

void QcPickResultListItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    if (!index.model()->hasChildren(index))
        return super_::paint(painter, option, index);

    auto opt = option;
    initStyleOption(&opt, index);

    auto view = dynamic_cast<const QcGroupedListView*>(option.widget);
    Q_ASSERT(view);

    auto branchWidth = view->branchWidth();
    auto style = view->style();

    bool branchHover = opt.state.testFlag(QStyle::State_MouseOver);
    branchHover = (index.row() == view->hoverBranchRow());
    bool rowHover = opt.state.testFlag(QStyle::State_MouseOver) && !branchHover; // branch高亮时取消行的高亮显示

    // 绘制行背景，确保把branch包进去
    opt.state.setFlag(QStyle::State_MouseOver, rowHover);
    style->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, painter, view);

    auto right = opt.rect.right();
    opt.rect.setWidth(branchWidth);

    opt.state.setFlag(QStyle::State_MouseOver, branchHover);
    style->drawPrimitive(QStyle::PE_IndicatorBranch, &opt, painter, view);
    opt.rect.setLeft(opt.rect.right());
    opt.rect.setRight(right);

    // 绘制list-item的标准内容
    opt.state.setFlag(QStyle::State_MouseOver, rowHover);
    style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, view);

    // 计算绘制内容的尺寸大小
    auto sz = style->sizeFromContents(QStyle::CT_ItemViewItem, &opt, QSize(), view);

    // 在标准内容之后绘制延长线
    opt.rect.adjust(sz.width(), 0, 0, 0);
    style->drawPrimitive(QStyle::PE_IndicatorToolBarSeparator, &opt, painter, view);
}

QSize QcPickResultListItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    auto view = dynamic_cast<const QcGroupedListView*>(option.widget);

    if (index.model()->hasChildren(index)) { // 修正分组根节点的尺寸
        auto sz = QStyledItemDelegate::sizeHint(option, index);
        sz.setWidth(view ? view->viewport()->width() : option.widget->width()); // 设置宽为全尺寸，确保独占一行
        return sz;
    }

    auto p = dynamic_cast<QcPickResultView*>(view->parent());
    Q_ASSERT(p);
    if (!p->isListRowVisible(index.row()))
        return QSize(0, 0); // 未展开，不显示

    // 直接使用固定尺寸，否则当大数据量时，动态计算尺寸会严重拖慢运行速度
    auto sz = view->iconSize();
    if (p->showDisplayRole())
        sz.rheight() += option.fontMetrics.height() * 2; // 最多显示2行文字
    sz.rwidth() += view->style()->subElementRect(QStyle::SE_CheckBoxIndicator, &option).width(); // 为checkbox预留位置
    sz += { 12, 8 }; // paddings
    return  sz;
}

void QcPickResultListItemDelegate::initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const
{
    super_::initStyleOption(option, index);

    auto view = dynamic_cast<const QcGroupedListView*>(option->widget);
    auto p = dynamic_cast<QcPickResultView*>(view->parent());
    Q_ASSERT(p);

    if (index.model()->hasChildren(index)) {
        option->viewItemPosition = QStyleOptionViewItem::OnlyOne;
        option->decorationPosition = QStyleOptionViewItem::Left;
        option->decorationAlignment = Qt::AlignCenter;
        option->displayAlignment = Qt::AlignLeft | Qt::AlignVCenter; // 标题始终靠左显示.
        option->features.setFlag(QStyleOptionViewItem::WrapText, false);
        option->features.setFlag(QStyleOptionViewItem::HasCheckIndicator, false); // 暂不显示checkbox，由于要绘制branch，目前尚未解决定位偏差问题
        option->state |= QStyle::State_Children; // 标记"有孩"状态

        if (p->isListRowExpanded(index.row())) // 判断是否展开
            option->state |= QStyle::State_Open;
    }
    else {
        option->decorationSize = view->iconSize();
        option->decorationAlignment = Qt::AlignCenter;
        option->displayAlignment = Qt::AlignTop | Qt::AlignHCenter;
        option->features.setFlag(QStyleOptionViewItem::WrapText, true);
        option->features.setFlag(QStyleOptionViewItem::HasDisplay, p->showDisplayRole());
    }
}
